<html><head>
      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
   <title>22.&nbsp;JMS (Java Message Service)</title><link rel="stylesheet" href="css/stylesheet.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"><link rel="home" href="index.html" title="Reference Documentation"><link rel="up" href="spring-integration.html" title="Part&nbsp;VI.&nbsp;Integration"><link rel="prev" href="ejb.html" title="21.&nbsp;Enterprise JavaBeans (EJB) integration"><link rel="next" href="jmx.html" title="23.&nbsp;JMX"><!--Begin Google Analytics code--><script type="text/javascript">
			var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
			document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
		</script><script type="text/javascript">
			var pageTracker = _gat._getTracker("UA-2728886-3");
			pageTracker._setDomainName("none");
			pageTracker._setAllowLinker(true);
			pageTracker._trackPageview();
		</script><!--End Google Analytics code--></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">22.&nbsp;JMS (Java Message Service)</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ejb.html">Prev</a>&nbsp;</td><th width="60%" align="center">Part&nbsp;VI.&nbsp;Integration</th><td width="20%" align="right">&nbsp;<a accesskey="n" href="jmx.html">Next</a></td></tr></table><hr></div><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="jms"></a>22.&nbsp;JMS (Java Message Service)</h2></div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="jms-introduction"></a>22.1&nbsp;Introduction</h2></div></div></div><p>Spring provides a JMS integration framework that simplifies the use
    of the JMS API much like Spring's integration does for the JDBC
    API.</p><p>JMS can be roughly divided into two areas of functionality, namely
    the production and consumption of messages. The
    <code class="classname">JmsTemplate</code> class is used for message production
    and synchronous message reception. For asynchronous reception similar to
    Java EE's message-driven bean style, Spring provides a number of message
    listener containers that are used to create Message-Driven POJOs
    (MDPs).</p><p>The package <code class="literal">org.springframework.jms.core</code> provides
    the core functionality for using JMS. It contains JMS template classes
    that simplify the use of the JMS by handling the creation and release of
    resources, much like the <code class="classname">JdbcTemplate</code> does for
    JDBC. The design principle common to Spring template classes is to provide
    helper methods to perform common operations and for more sophisticated
    usage, delegate the essence of the processing task to user implemented
    callback interfaces. The JMS template follows the same design. The classes
    offer various convenience methods for the sending of messages, consuming a
    message synchronously, and exposing the JMS session and message producer
    to the user.</p><p>The package <code class="literal">org.springframework.jms.support</code>
    provides <code class="classname">JMSException</code> translation functionality.
    The translation converts the checked <code class="classname">JMSException</code>
    hierarchy to a mirrored hierarchy of unchecked exceptions. If there are
    any provider specific subclasses of the checked
    <code class="classname">javax.jms.JMSException</code>, this exception is wrapped
    in the unchecked <code class="classname">UncategorizedJmsException</code>.</p><p>The package
    <code class="literal">org.springframework.jms.support.converter</code> provides a
    <code class="interfacename">MessageConverter</code> abstraction to convert
    between Java objects and JMS messages.</p><p>The package
    <code class="literal">org.springframework.jms.support.destination</code> provides
    various strategies for managing JMS destinations, such as providing a
    service locator for destinations stored in JNDI.</p><p>Finally, the package
    <code class="literal">org.springframework.jms.connection</code> provides an
    implementation of the <code class="classname">ConnectionFactory</code> suitable
    for use in standalone applications. It also contains an implementation of
    Spring's <code class="interfacename">PlatformTransactionManager</code> for JMS
    (the cunningly named <code class="classname">JmsTransactionManager</code>). This
    allows for seamless integration of JMS as a transactional resource into
    Spring's transaction management mechanisms.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="jms-using"></a>22.2&nbsp;Using Spring JMS</h2></div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="jms-jmstemplate"></a>22.2.1&nbsp;<code class="classname">JmsTemplate</code></h3></div></div></div><p>The <code class="classname">JmsTemplate</code> class is the central class
      in the JMS core package. It simplifies the use of JMS since it handles
      the creation and release of resources when sending or synchronously
      receiving messages.</p><p>Code that uses the <code class="classname">JmsTemplate</code> only needs
      to implement callback interfaces giving them a clearly defined high
      level contract. The <code class="classname">MessageCreator</code> callback
      interface creates a message given a
      <code class="interfacename">Session</code> provided by the calling code in
      <code class="classname">JmsTemplate</code>. In order to allow for more complex
      usage of the JMS API, the callback
      <code class="classname">SessionCallback</code> provides the user with the JMS
      session and the callback <code class="classname">ProducerCallback</code> exposes
      a <code class="interfacename">Session</code> and
      <code class="interfacename">MessageProducer</code> pair.</p><p>The JMS API exposes two types of send methods, one that takes
      delivery mode, priority, and time-to-live as Quality of Service (QOS)
      parameters and one that takes no QOS parameters which uses default
      values. Since there are many send methods in
      <code class="classname">JmsTemplate</code>, the setting of the QOS parameters
      have been exposed as bean properties to avoid duplication in the number
      of send methods. Similarly, the timeout value for synchronous receive
      calls is set using the property
      <code class="classname">setReceiveTimeout</code>.</p><p>Some JMS providers allow the setting of default QOS values
      administratively through the configuration of the ConnectionFactory.
      This has the effect that a call to
      <code class="classname">MessageProducer</code>'s send method
      <code class="methodname">send(Destination destination, Message message)</code>
      will use different QOS default values than those specified in the JMS
      specification. In order to provide consistent management of QOS values,
      the <code class="classname">JmsTemplate</code> must therefore be specifically
      enabled to use its own QOS values by setting the boolean property
      <span class="property">isExplicitQosEnabled</span> to
      <code class="literal">true</code>.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.gif"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>Instances of the <code class="classname">JmsTemplate</code> class are
        <span class="emphasis"><em>thread-safe once configured</em></span>. This is important
        because it means that you can configure a single instance of a
        <code class="classname">JmsTemplate</code> and then safely inject this
        <span class="emphasis"><em>shared</em></span> reference into multiple collaborators. To
        be clear, the <code class="classname">JmsTemplate</code> is stateful, in that
        it maintains a reference to a
        <code class="interfacename">ConnectionFactory</code>, but this state is
        <span class="emphasis"><em>not</em></span> conversational state.</p></td></tr></table></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="jms-connections"></a>22.2.2&nbsp;Connections</h3></div></div></div><p>The <code class="classname">JmsTemplate</code> requires a reference to a
      <code class="classname">ConnectionFactory</code>. The
      <code class="classname">ConnectionFactory</code> is part of the JMS
      specification and serves as the entry point for working with JMS. It is
      used by the client application as a factory to create connections with
      the JMS provider and encapsulates various configuration parameters, many
      of which are vendor specific such as SSL configuration options.</p><p>When using JMS inside an EJB, the vendor provides implementations
      of the JMS interfaces so that they can participate in declarative
      transaction management and perform pooling of connections and sessions.
      In order to use this implementation, Java EE containers typically
      require that you declare a JMS connection factory as a
      <span class="property">resource-ref</span> inside the EJB or servlet deployment
      descriptors. To ensure the use of these features with the
      <code class="classname">JmsTemplate</code> inside an EJB, the client application
      should ensure that it references the managed implementation of the
      <code class="classname">ConnectionFactory</code>.</p><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e37993"></a>22.2.2.1&nbsp;Caching Messaging Resources</h4></div></div></div><p>The standard API involves creating many intermediate objects. To
        send a message the following 'API' walk is performed</p><pre class="programlisting">ConnectionFactory-&gt;Connection-&gt;Session-&gt;MessageProducer-&gt;send</pre><p>Between the ConnectionFactory and the Send operation there are
        three intermediate objects that are created and destroyed. To optimise
        the resource usage and increase performance two implementations of
        IConnectionFactory are provided.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e38002"></a>22.2.2.2&nbsp;SingleConnectionFactory</h4></div></div></div><p>Spring provides an implementation of the
        <code class="classname">ConnectionFactory</code> interface,
        <code class="classname">SingleConnectionFactory</code>, that will return the
        same <code class="classname">Connection</code> on all
        <code class="methodname">createConnection()</code> calls and ignore calls to
        <code class="methodname">close()</code>. This is useful for testing and
        standalone environments so that the same connection can be used for
        multiple <code class="classname">JmsTemplate</code> calls that may span any
        number of transactions. <code class="classname">SingleConnectionFactory</code>
        takes a reference to a standard
        <code class="classname">ConnectionFactory</code> that would typically come
        from JNDI.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e38031"></a>22.2.2.3&nbsp;CachingConnectionFactory</h4></div></div></div><p>The <code class="classname">CachingConnectionFactory</code> extends the
        functionality of <code class="classname">SingleConnectionFactory</code> and
        adds the caching of Sessions, MessageProducers, and MessageConsumers.
        The initial cache size is set to 1, use the property
        <span class="property">SessionCacheSize</span> to increase the number of cached
        sessions. Note that the number of actual cached sessions will be more
        than that number as sessions are cached based on their acknowledgment
        mode, so there can be up to 4 cached session instances when
        <span class="property">SessionCacheSize</span> is set to one, one for each
        AcknowledgementMode. MessageProducers and MessageConsumers are cached
        within their owning session and also take into account the unique
        properties of the producers and consumers when caching.
        MessageProducers are cached based on their destination.
        MessageConsumers are cached based on a key composed of the
        destination, selector, noLocal delivery flag, and the durable
        subscription name (if creating durable consumers).</p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="jms-destinations"></a>22.2.3&nbsp;Destination Management</h3></div></div></div><p>Destinations, like ConnectionFactories, are JMS administered
      objects that can be stored and retrieved in JNDI. When configuring a
      Spring application context you can use the JNDI factory class
      <code class="classname">JndiObjectFactoryBean</code> /
      <code class="literal">&lt;jee:jndi-lookup&gt;</code> to perform dependency
      injection on your object's references to JMS destinations. However,
      often this strategy is cumbersome if there are a large number of
      destinations in the application or if there are advanced destination
      management features unique to the JMS provider. Examples of such
      advanced destination management would be the creation of dynamic
      destinations or support for a hierarchical namespace of destinations.
      The <code class="classname">JmsTemplate</code> delegates the resolution of a
      destination name to a JMS destination object to an implementation of the
      interface <code class="classname">DestinationResolver</code>.
      <code class="classname">DynamicDestinationResolver</code> is the default
      implementation used by <code class="classname">JmsTemplate</code> and
      accommodates resolving dynamic destinations. A
      <code class="classname">JndiDestinationResolver</code> is also provided that
      acts as a service locator for destinations contained in JNDI and
      optionally falls back to the behavior contained in
      <code class="classname">DynamicDestinationResolver</code>.</p><p>Quite often the destinations used in a JMS application are only
      known at runtime and therefore cannot be administratively created when
      the application is deployed. This is often because there is shared
      application logic between interacting system components that create
      destinations at runtime according to a well-known naming convention.
      Even though the creation of dynamic destinations is not part of the JMS
      specification, most vendors have provided this functionality. Dynamic
      destinations are created with a name defined by the user which
      differentiates them from temporary destinations and are often not
      registered in JNDI. The API used to create dynamic destinations varies
      from provider to provider since the properties associated with the
      destination are vendor specific. However, a simple implementation choice
      that is sometimes made by vendors is to disregard the warnings in the
      JMS specification and to use the <code class="classname">TopicSession</code>
      method <code class="methodname">createTopic(String topicName)</code> or the
      <code class="classname">QueueSession</code> method
      <code class="methodname">createQueue(String queueName)</code> to create a new
      destination with default destination properties. Depending on the vendor
      implementation, <code class="classname">DynamicDestinationResolver</code> may
      then also create a physical destination instead of only resolving
      one.</p><p>The boolean property <span class="property">pubSubDomain</span> is used to
      configure the <code class="classname">JmsTemplate</code> with knowledge of what
      JMS domain is being used. By default the value of this property is
      false, indicating that the point-to-point domain, Queues, will be used.
      This property used by <code class="classname">JmsTemplate</code> determines the
      behavior of dynamic destination resolution via implementations of the
      <code class="interfacename">DestinationResolver</code> interface.</p><p>You can also configure the <code class="classname">JmsTemplate</code> with
      a default destination via the property
      <span class="property">defaultDestination</span>. The default destination will be
      used with send and receive operations that do not refer to a specific
      destination.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="jms-mdp"></a>22.2.4&nbsp;Message Listener Containers</h3></div></div></div><p>One of the most common uses of JMS messages in the EJB world is to
      drive message-driven beans (MDBs). Spring offers a solution to create
      message-driven POJOs (MDPs) in a way that does not tie a user to an EJB
      container. (See <a class="xref" href="jms.html#jms-asynchronousMessageReception" title="22.4.2&nbsp;Asynchronous Reception - Message-Driven POJOs">Section&nbsp;22.4.2, &#8220;Asynchronous Reception - Message-Driven POJOs&#8221;</a>
      for detailed coverage of Spring's MDP support.)</p><p>A message listener container is used to receive messages from a
      JMS message queue and drive the MessageListener that is injected into
      it. The listener container is responsible for all threading of message
      reception and dispatches into the listener for processing. A message
      listener container is the intermediary between an MDP and a messaging
      provider, and takes care of registering to receive messages,
      participating in transactions, resource acquisition and release,
      exception conversion and suchlike. This allows you as an application
      developer to write the (possibly complex) business logic associated with
      receiving a message (and possibly responding to it), and delegates
      boilerplate JMS infrastructure concerns to the framework.</p><p>There are two standard JMS message listener containers packaged
      with Spring, each with its specialised feature set.</p><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="jms-mdp-simple"></a>22.2.4.1&nbsp;SimpleMessageListenerContainer</h4></div></div></div><p>This message listener container is the simpler of the two
        standard flavors. It creates a fixed number of JMS sessions and
        consumers at startup, registers the listener using the standard JMS
        <code class="methodname">MessageConsumer.setMessageListener()</code> method,
        and leaves it up the JMS provider to perform listener callbacks.
        This variant does not allow for dynamic adaption to runtime demands or
        for participation in externally managed transactions. Compatibility-wise,
        it stays very close to the spirit of the standalone JMS specification
        - but is generally not compatible with Java EE's JMS restrictions.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="jms-mdp-default"></a>22.2.4.2&nbsp;DefaultMessageListenerContainer</h4></div></div></div><p>This message listener container is the one used in most cases.
        In contrast to <code class="classname">SimpleMessageListenerContainer</code>,
        this container variant does allow for dynamic adaption to runtime
        demands and is able to participate in externally managed transactions.
        Each received message is registered with an XA transaction when
        configured with a <code class="classname">JtaTransactionManager</code>; so
        processing may take advantage of XA transaction semantics. This
        listener container strikes a good balance between low requirements on
        the JMS provider, advanced functionality such as transaction
        participation, and compatibility with Java EE environments.</p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="jms-tx"></a>22.2.5&nbsp;Transaction management</h3></div></div></div><p>Spring provides a <code class="classname">JmsTransactionManager</code>
      that manages transactions for a single JMS
      <code class="classname">ConnectionFactory</code>. This allows JMS applications
      to leverage the managed transaction features of Spring as described in
      <a class="xref" href="transaction.html" title="11.&nbsp;Transaction Management">Chapter&nbsp;11, <i>Transaction Management</i></a>. The
      <code class="classname">JmsTransactionManager</code> performs local resource
      transactions, binding a JMS Connection/Session pair from the specified
      <code class="classname">ConnectionFactory</code> to the thread.
      <code class="classname">JmsTemplate</code> automatically detects such
      transactional resources and operates on them accordingly.</p><p>In a Java EE environment, the
      <code class="classname">ConnectionFactory</code> will pool Connections and
      Sessions, so those resources are efficiently reused across transactions.
      In a standalone environment, using Spring's
      <code class="classname">SingleConnectionFactory</code> will result in a shared
      JMS <code class="classname">Connection</code>, with each transaction having its
      own independent <code class="classname">Session</code>. Alternatively, consider
      the use of a provider-specific pooling adapter such as ActiveMQ's
      <code class="classname">PooledConnectionFactory</code> class.</p><p><code class="classname">JmsTemplate</code> can also be used with the
      <code class="classname">JtaTransactionManager</code> and an XA-capable JMS
      <code class="classname">ConnectionFactory</code> for performing distributed
      transactions. Note that this requires the use of a JTA transaction
      manager as well as a properly XA-configured ConnectionFactory! (Check
      your Java EE server's / JMS provider's documentation.)</p><p>Reusing code across a managed and unmanaged transactional
      environment can be confusing when using the JMS API to create a
      <code class="classname">Session</code> from a <code class="classname">Connection</code>.
      This is because the JMS API has only one factory method to create a
      <code class="classname">Session</code> and it requires values for the
      transaction and acknowledgement modes. In a managed environment, setting
      these values is the responsibility of the environment's transactional
      infrastructure, so these values are ignored by the vendor's wrapper to
      the JMS Connection. When using the <code class="classname">JmsTemplate</code> in
      an unmanaged environment you can specify these values through the use of
      the properties <code class="literal">sessionTransacted</code> and
      <code class="literal">sessionAcknowledgeMode</code>. When using a
      <code class="classname">PlatformTransactionManager</code> with
      <code class="classname">JmsTemplate</code>, the template will always be given a
      transactional JMS <code class="classname">Session</code>.</p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="jms-sending"></a>22.3&nbsp;Sending a <code class="interfacename">Message</code></h2></div></div></div><p>The <code class="classname">JmsTemplate</code> contains many convenience
    methods to send a message. There are send methods that specify the
    destination using a <code class="classname">javax.jms.Destination</code> object
    and those that specify the destination using a string for use in a JNDI
    lookup. The send method that takes no destination argument uses the
    default destination. Here is an example that sends a message to a queue
    using the 1.0.2 implementation.</p><pre class="programlisting"><span class="hl-keyword">import</span> javax.jms.ConnectionFactory;
<span class="hl-keyword">import</span> javax.jms.JMSException;
<span class="hl-keyword">import</span> javax.jms.Message;
<span class="hl-keyword">import</span> javax.jms.Queue;
<span class="hl-keyword">import</span> javax.jms.Session;

<span class="hl-keyword">import</span> org.springframework.jms.core.MessageCreator;
<span class="hl-keyword">import</span> org.springframework.jms.core.JmsTemplate;

<span class="hl-keyword">public</span> <span class="hl-keyword">class</span> JmsQueueSender {

    <span class="hl-keyword">private</span> JmsTemplate jmsTemplate;
    <span class="hl-keyword">private</span> Queue queue;

    <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> setConnectionFactory(ConnectionFactory cf) {
        <span class="hl-keyword">this</span>.jmsTemplate = <span class="hl-keyword">new</span> JmsTemplate(cf);
    }

    <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> setQueue(Queue queue) {
        <span class="hl-keyword">this</span>.queue = queue;
    }

    <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> simpleSend() {
        <span class="hl-keyword">this</span>.jmsTemplate.send(<span class="hl-keyword">this</span>.queue, <span class="hl-keyword">new</span> MessageCreator() {
            <span class="hl-keyword">public</span> Message createMessage(Session session) <span class="hl-keyword">throws</span> JMSException {
              <span class="hl-keyword">return</span> session.createTextMessage(<span class="hl-string">"hello queue world"</span>);
            }
        });
    }
}</pre><p>This example uses the <code class="classname">MessageCreator</code> callback
    to create a text message from the supplied <code class="classname">Session</code>
    object. The <code class="classname">JmsTemplate</code> is constructed by passing a
    reference to a <code class="classname">ConnectionFactory</code>. As an alternative,
    a zero argument constructor and <span class="property">connectionFactory</span>
    is provided and can be used for constructing the instance in JavaBean style
    (using a BeanFactory or plain Java code). Alternatively, consider deriving
    from Spring's <code class="classname">JmsGatewaySupport</code> convenience base class,
    which provides pre-built bean properties for JMS configuration.</p><p>The method <code class="methodname">send(String destinationName, MessageCreator
    creator)</code> lets you send a message using the string name of
    the destination. If these names are registered in JNDI, you should set the
    <span class="property">destinationResolver</span> property of the template to an
    instance of <code class="classname">JndiDestinationResolver</code>.</p><p>If you created the <code class="classname">JmsTemplate</code> and specified
    a default destination, the <code class="methodname">send(MessageCreator c)</code>
    sends a message to that destination.</p><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="jms-msg-conversion"></a>22.3.1&nbsp;Using Message Converters</h3></div></div></div><p>In order to facilitate the sending of domain model objects, the
      <code class="classname">JmsTemplate</code> has various send methods that take a
      Java object as an argument for a message's data content. The overloaded
      methods <code class="methodname">convertAndSend()</code> and
      <code class="methodname">receiveAndConvert()</code> in
      <code class="classname">JmsTemplate</code> delegate the conversion process to an
      instance of the <code class="literal">MessageConverter</code> interface. This
      interface defines a simple contract to convert between Java objects and
      JMS messages. The default implementation
      <code class="classname">SimpleMessageConverter</code> supports conversion
      between <code class="classname">String</code> and
      <code class="classname">TextMessage</code>, <code class="classname">byte[]</code> and
      <code class="classname">BytesMesssage</code>, and
      <code class="classname">java.util.Map</code> and
      <code class="classname">MapMessage</code>. By using the converter, you and your
      application code can focus on the business object that is being sent or
      received via JMS and not be concerned with the details of how it is
      represented as a JMS message.</p><p>The sandbox currently includes a
      <code class="classname">MapMessageConverter</code> which uses reflection to
      convert between a JavaBean and a <code class="classname">MapMessage</code>.
      Other popular implementation choices you might implement yourself are
      Converters that use an existing XML marshalling package, such as JAXB,
      Castor, XMLBeans, or XStream, to create a
      <code class="interfacename">TextMessage</code> representing the
      object.</p><p>To accommodate the setting of a message's properties, headers, and
      body that can not be generically encapsulated inside a converter class,
      the <code class="interfacename">MessagePostProcessor</code> interface gives
      you access to the message after it has been converted, but before it is
      sent. The example below demonstrates how to modify a message header and
      a property after a <code class="interfacename">java.util.Map</code> is
      converted to a message.</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">void</span> sendWithConversion() {
    Map map = <span class="hl-keyword">new</span> HashMap();
    map.put(<span class="hl-string">"Name"</span>, <span class="hl-string">"Mark"</span>);
    map.put(<span class="hl-string">"Age"</span>, <span class="hl-keyword">new</span> Integer(47));
    jmsTemplate.convertAndSend(<span class="hl-string">"testQueue"</span>, map, <span class="hl-keyword">new</span> MessagePostProcessor() {
        <span class="hl-keyword">public</span> Message postProcessMessage(Message message) <span class="hl-keyword">throws</span> JMSException {
            message.setIntProperty(<span class="hl-string">"AccountID"</span>, 1234);
            message.setJMSCorrelationID(<span class="hl-string">"123-00001"</span>);
            <span class="hl-keyword">return</span> message;
        }
    });
}</pre><p>This results in a message of the form:</p><pre class="programlisting">MapMessage={
    Header={
        ... standard headers ...
        CorrelationID={123-00001}
    }
    Properties={
        AccountID={Integer:1234}
    }
    Fields={
        Name={String:Mark}
        Age={Integer:47}
    } 
}</pre></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="jms-callbacks"></a>22.3.2&nbsp;<code class="interfacename">SessionCallback</code> and
      <code class="interfacename">ProducerCallback</code></h3></div></div></div><p>While the send operations cover many common usage scenarios, there
      are cases when you want to perform multiple operations on a JMS
      <code class="interfacename">Session</code> or
      <code class="interfacename">MessageProducer</code>. The
      <code class="interfacename">SessionCallback</code> and
      <code class="interfacename">ProducerCallback</code> expose the JMS
      <code class="interfacename">Session</code> and
      <code class="interfacename">Session</code> /
      <code class="interfacename">MessageProducer</code> pair respectively. The
      <code class="methodname">execute()</code> methods on
      <code class="classname">JmsTemplate</code> execute these callback
      methods.</p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="jms-receiving"></a>22.4&nbsp;Receiving a message</h2></div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="jms-receiving-sync"></a>22.4.1&nbsp;Synchronous Reception</h3></div></div></div><p>While JMS is typically associated with asynchronous processing, it
      is possible to consume messages synchronously. The overloaded
      <code class="methodname">receive(..)</code> methods provide this functionality.
      During a synchronous receive, the calling thread blocks until a message
      becomes available. This can be a dangerous operation since the calling
      thread can potentially be blocked indefinitely. The property
      <span class="property">receiveTimeout</span> specifies how long the receiver
      should wait before giving up waiting for a message.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="jms-asynchronousMessageReception"></a>22.4.2&nbsp;Asynchronous Reception - Message-Driven POJOs</h3></div></div></div><p>In a fashion similar to a Message-Driven Bean (MDB) in the EJB
      world, the Message-Driven POJO (MDP) acts as a receiver for JMS
      messages. The one restriction (but see also below for the discussion of
      the <code class="classname">MessageListenerAdapter</code> class) on an MDP is
      that it must implement the
      <code class="interfacename">javax.jms.MessageListener</code> interface.
      Please also be aware that in the case where your POJO will be receiving
      messages on multiple threads, it is important to ensure that your
      implementation is thread-safe.</p><p>Below is a simple implementation of an MDP:</p><pre class="programlisting"><span class="hl-keyword">import</span> javax.jms.JMSException;
<span class="hl-keyword">import</span> javax.jms.Message;
<span class="hl-keyword">import</span> javax.jms.MessageListener;
<span class="hl-keyword">import</span> javax.jms.TextMessage;

<span class="hl-keyword">public</span> <span class="hl-keyword">class</span> ExampleListener <span class="hl-keyword">implements</span> MessageListener {

    <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> onMessage(Message message) {
        <span class="hl-keyword">if</span> (message <span class="hl-keyword">instanceof</span> TextMessage) {
            <span class="hl-keyword">try</span> {
                System.out.println(((TextMessage) message).getText());
            }
            <span class="hl-keyword">catch</span> (JMSException ex) {
                <span class="hl-keyword">throw</span> <span class="hl-keyword">new</span> RuntimeException(ex);
            }
        }
        <span class="hl-keyword">else</span> {
            <span class="hl-keyword">throw</span> <span class="hl-keyword">new</span> IllegalArgumentException(<span class="hl-string">"Message must be of type TextMessage"</span>);
        }
    }
}</pre><p>Once you've implemented your
      <code class="interfacename">MessageListener</code>, it's time to create a
      message listener container.</p><p>Find below an example of how to define and configure one of the
      message listener containers that ships with Spring (in this case the
      <code class="classname">DefaultMessageListenerContainer</code>).</p><pre class="programlisting">&lt;<span class="hl-comment">!-- this is the Message Driven POJO (MDP) --</span>&gt;
&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"messageListener"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"jmsexample.ExampleListener"</span> /&gt;

&lt;<span class="hl-comment">!-- and this is the message listener container --</span>&gt;
&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"jmsContainer"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.jms.listener.DefaultMessageListenerContainer"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"connectionFactory"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"connectionFactory"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"destination"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"destination"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"messageListener"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"messageListener"</span> /&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</pre><p>Please refer to the Spring Javadoc of the various message listener
      containers for a full description of the features supported by each
      implementation.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="jms-receiving-async-session-aware-message-listener"></a>22.4.3&nbsp;The <code class="interfacename">SessionAwareMessageListener</code>
      interface</h3></div></div></div><p>The <code class="interfacename">SessionAwareMessageListener</code>
      interface is a Spring-specific interface that provides a similar
      contract to the JMS <code class="interfacename">MessageListener</code>
      interface, but also provides the message handling method with access to
      the JMS <code class="interfacename">Session</code> from which the
      <code class="interfacename">Message</code> was received.</p><pre class="programlisting"><span class="hl-keyword">package</span> org.springframework.jms.listener;

<span class="hl-keyword">public</span> <span class="hl-keyword">interface</span> SessionAwareMessageListener {

    <span class="hl-keyword">void</span> onMessage(Message message, Session session) <span class="hl-keyword">throws</span> JMSException;
}</pre><p>You can choose to have your MDPs implement this interface (in
      preference to the standard JMS
      <code class="interfacename">MessageListener</code> interface) if you want
      your MDPs to be able to respond to any received messages (using the
      <code class="interfacename">Session</code> supplied in the
      <code class="literal">onMessage(Message, Session)</code> method). All of the
      message listener container implementations that ship with Spring have
      support for MDPs that implement either the
      <code class="interfacename">MessageListener</code> or
      <code class="interfacename">SessionAwareMessageListener</code> interface.
      Classes that implement the
      <code class="interfacename">SessionAwareMessageListener</code> come with the
      caveat that they are then tied to Spring through the interface. The
      choice of whether or not to use it is left entirely up to you as an
      application developer or architect.</p><p>Please note that the <code class="literal">'onMessage(..)'</code> method of
      the <code class="interfacename">SessionAwareMessageListener</code> interface
      throws <code class="classname">JMSException</code>. In contrast to the standard
      JMS <code class="interfacename">MessageListener</code> interface, when using
      the <code class="interfacename">SessionAwareMessageListener</code>
      interface, it is the responsibility of the client code to handle any
      exceptions thrown.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="jms-receiving-async-message-listener-adapter"></a>22.4.4&nbsp;The <code class="classname">MessageListenerAdapter</code></h3></div></div></div><p>The <code class="classname">MessageListenerAdapter</code> class is the
      final component in Spring's asynchronous messaging support: in a
      nutshell, it allows you to expose almost <span class="emphasis"><em>any</em></span> class
      as a MDP (there are of course some constraints).</p><p>Consider the following interface definition. Notice that although
      the interface extends neither the
      <code class="interfacename">MessageListener</code> nor
      <code class="interfacename">SessionAwareMessageListener</code> interfaces,
      it can still be used as a MDP via the use of the
      <code class="classname">MessageListenerAdapter</code> class. Notice also how the
      various message handling methods are strongly typed according to the
      <span class="emphasis"><em>contents</em></span> of the various
      <code class="interfacename">Message</code> types that they can receive and
      handle.</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">interface</span> MessageDelegate {

    <span class="hl-keyword">void</span> handleMessage(String message);

    <span class="hl-keyword">void</span> handleMessage(Map message);

    <span class="hl-keyword">void</span> handleMessage(<span class="hl-keyword">byte</span>[] message);

    <span class="hl-keyword">void</span> handleMessage(Serializable message);
}</pre><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">class</span> DefaultMessageDelegate <span class="hl-keyword">implements</span> MessageDelegate {
    <span class="hl-comment">// implementation elided for clarity...</span>
}</pre><p>In particular, note how the above implementation of the
      <code class="interfacename">MessageDelegate</code> interface (the above
      <code class="classname">DefaultMessageDelegate</code> class) has
      <span class="emphasis"><em>no</em></span> JMS dependencies at all. It truly is a POJO that
      we will make into an MDP via the following configuration.</p><pre class="programlisting">&lt;<span class="hl-comment">!-- this is the Message Driven POJO (MDP) --</span>&gt;
&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"messageListener"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.jms.listener.adapter.MessageListenerAdapter"</span>&gt;
    &lt;<span class="hl-tag">constructor-arg</span>&gt;
        &lt;<span class="hl-tag">bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"jmsexample.DefaultMessageDelegate"</span>/&gt;
    &lt;<span class="hl-tag">/constructor-arg</span>&gt;
&lt;<span class="hl-tag">/bean</span>&gt;

&lt;<span class="hl-comment">!-- and this is the message listener container... --</span>&gt;
&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"jmsContainer"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.jms.listener.DefaultMessageListenerContainer"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"connectionFactory"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"connectionFactory"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"destination"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"destination"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"messageListener"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"messageListener"</span> /&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</pre><p>Below is an example of another MDP that can only handle the
      receiving of JMS <code class="interfacename">TextMessage</code> messages.
      Notice how the message handling method is actually called
      <code class="literal">'receive'</code> (the name of the message handling method in
      a <code class="classname">MessageListenerAdapter</code> defaults to
      <code class="literal">'handleMessage'</code>), but it is configurable (as you will
      see below). Notice also how the <code class="literal">'receive(..)'</code> method
      is strongly typed to receive and respond only to JMS
      <code class="interfacename">TextMessage</code> messages.</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">interface</span> TextMessageDelegate {

    <span class="hl-keyword">void</span> receive(TextMessage message);
}</pre><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">class</span> DefaultTextMessageDelegate <span class="hl-keyword">implements</span> TextMessageDelegate {
    <span class="hl-comment">// implementation elided for clarity...</span>
}</pre><p>The configuration of the attendant
      <code class="classname">MessageListenerAdapter</code> would look like
      this:</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"messageListener"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.jms.listener.adapter.MessageListenerAdapter"</span>&gt;
    &lt;<span class="hl-tag">constructor-arg</span>&gt;
        &lt;<span class="hl-tag">bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"jmsexample.DefaultTextMessageDelegate"</span>/&gt;
    &lt;<span class="hl-tag">/constructor-arg</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"defaultListenerMethod"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"receive"</span>/&gt;
    &lt;<span class="hl-comment">!-- we don't want automatic message context extraction --</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"messageConverter"</span>&gt;
        &lt;<span class="hl-tag">null</span>/&gt;
    &lt;<span class="hl-tag">/property</span>&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</pre><p>Please note that if the above <code class="literal">'messageListener'</code>
      receives a JMS <code class="interfacename">Message</code> of a type other
      than <code class="interfacename">TextMessage</code>, an
      <code class="classname">IllegalStateException</code> will be thrown (and
      subsequently swallowed). Another of the capabilities of the
      <code class="classname">MessageListenerAdapter</code> class is the ability to
      automatically send back a response
      <code class="interfacename">Message</code> if a handler method returns a
      non-void value. Consider the interface and class:</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">interface</span> ResponsiveTextMessageDelegate {

    <span class="hl-comment">// notice the return type...</span>
    String receive(TextMessage message);
}</pre><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">class</span> DefaultResponsiveTextMessageDelegate <span class="hl-keyword">implements</span> ResponsiveTextMessageDelegate {
    <span class="hl-comment">// implementation elided for clarity...</span>
}</pre><p>If the above
      <code class="classname">DefaultResponsiveTextMessageDelegate</code> is used in
      conjunction with a <code class="classname">MessageListenerAdapter</code> then
      any non-null value that is returned from the execution of the
      <code class="literal">'receive(..)'</code> method will (in the default
      configuration) be converted into a
      <code class="interfacename">TextMessage</code>. The resulting
      <code class="interfacename">TextMessage</code> will then be sent to the
      <code class="interfacename">Destination</code> (if one exists) defined in
      the JMS Reply-To property of the original
      <code class="interfacename">Message</code>, or the default
      <code class="interfacename">Destination</code> set on the
      <code class="classname">MessageListenerAdapter</code> (if one has been
      configured); if no <code class="interfacename">Destination</code> is found
      then an <code class="classname">InvalidDestinationException</code> will be
      thrown (and please note that this exception <span class="emphasis"><em>will
      not</em></span> be swallowed and <span class="emphasis"><em>will</em></span> propagate up
      the call stack).</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="jms-tx-participation"></a>22.4.5&nbsp;Processing messages within transactions</h3></div></div></div><p>Invoking a message listener within a transaction only requires
      reconfiguration of the listener container.</p><p>Local resource transactions can simply be activated through the
      <code class="literal">sessionTransacted</code> flag on the listener container
      definition. Each message listener invocation will then operate within an
      active JMS transaction, with message reception rolled back in case of
      listener execution failure. Sending a response message (via
      <code class="interfacename">SessionAwareMessageListener</code>) will be part
      of the same local transaction, but any other resource operations (such
      as database access) will operate independently. This usually requires
      duplicate message detection in the listener implementation, covering the
      case where database processing has committed but message processing
      failed to commit.</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"jmsContainer"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.jms.listener.DefaultMessageListenerContainer"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"connectionFactory"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"connectionFactory"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"destination"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"destination"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"messageListener"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"messageListener"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"sessionTransacted"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"true"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</pre><p>For participating in an externally managed transaction, you will
      need to configure a transaction manager and use a listener container
      which supports externally managed transactions: typically
      <code class="classname">DefaultMessageListenerContainer</code>.</p><p>To configure a message listener container for XA transaction
      participation, you'll want to configure a
      <code class="classname">JtaTransactionManager</code> (which, by default,
      delegates to the Java EE server's transaction subsystem). Note that the
      underlying JMS ConnectionFactory needs to be XA-capable and properly
      registered with your JTA transaction coordinator! (Check your Java EE
      server's configuration of JNDI resources.) This allows message reception
      as well as e.g. database access to be part of the same transaction (with
      unified commit semantics, at the expense of XA transaction log
      overhead).</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"transactionManager"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.transaction.jta.JtaTransactionManager"</span>/&gt;
</pre><p>Then you just need to add it to our earlier container
      configuration. The container will take care of the rest.</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"jmsContainer"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.jms.listener.DefaultMessageListenerContainer"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"connectionFactory"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"connectionFactory"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"destination"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"destination"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"messageListener"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"messageListener"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"transactionManager"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"transactionManager"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</pre></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="jms-jca-message-endpoint-manager"></a>22.5&nbsp;Support for JCA Message Endpoints</h2></div></div></div><p>Beginning with version 2.5, Spring also provides support for a
    JCA-based <code class="interfacename">MessageListener</code> container. The
    <code class="classname">JmsMessageEndpointManager</code> will attempt to
    automatically determine the <code class="interfacename">ActivationSpec</code>
    class name from the provider's
    <code class="interfacename">ResourceAdapter</code> class name. Therefore, it
    is typically possible to just provide Spring's generic
    <code class="classname">JmsActivationSpecConfig</code> as shown in the following
    example.</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.jms.listener.endpoint.JmsMessageEndpointManager"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"resourceAdapter"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"resourceAdapter"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"activationSpecConfig"</span>&gt;
        &lt;<span class="hl-tag">bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.jms.listener.endpoint.JmsActivationSpecConfig"</span>&gt;
            &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"destinationName"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"myQueue"</span>/&gt;
        &lt;<span class="hl-tag">/bean</span>&gt;
    &lt;<span class="hl-tag">/property</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"messageListener"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"myMessageListener"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</pre><p>Alternatively, you may set up a
    <code class="classname">JmsMessageEndpointManager</code> with a given
    <code class="interfacename">ActivationSpec</code> object. The
    <code class="interfacename">ActivationSpec</code> object may also come from a
    JNDI lookup (using <code class="literal">&lt;jee:jndi-lookup&gt;</code>).</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.jms.listener.endpoint.JmsMessageEndpointManager"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"resourceAdapter"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"resourceAdapter"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"activationSpec"</span>&gt;
        &lt;<span class="hl-tag">bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.apache.activemq.ra.ActiveMQActivationSpec"</span>&gt;
            &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"destination"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"myQueue"</span>/&gt;
            &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"destinationType"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"javax.jms.Queue"</span>/&gt;
        &lt;<span class="hl-tag">/bean</span>&gt;
    &lt;<span class="hl-tag">/property</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"messageListener"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"myMessageListener"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</pre><p>Using Spring's <code class="classname">ResourceAdapterFactoryBean</code>,
    the target <code class="interfacename">ResourceAdapter</code> may be
    configured locally as depicted in the following example.</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"resourceAdapter"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.jca.support.ResourceAdapterFactoryBean"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"resourceAdapter"</span>&gt;
        &lt;<span class="hl-tag">bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.apache.activemq.ra.ActiveMQResourceAdapter"</span>&gt;
            &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serverUrl"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"tcp://localhost:61616"</span>/&gt;
        &lt;<span class="hl-tag">/bean</span>&gt;
    &lt;<span class="hl-tag">/property</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"workManager"</span>&gt;
        &lt;<span class="hl-tag">bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.jca.work.SimpleTaskWorkManager"</span>/&gt;
    &lt;<span class="hl-tag">/property</span>&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</pre><p>The specified <code class="interfacename">WorkManager</code> may also
    point to an environment-specific thread pool - typically through
    <code class="classname">SimpleTaskWorkManager's</code> "asyncTaskExecutor"
    property. Consider defining a shared thread pool for all your
    <code class="interfacename">ResourceAdapter</code> instances if you happen to
    use multiple adapters.</p><p>In some environments (e.g. WebLogic 9 or above), the entire
    <code class="interfacename">ResourceAdapter</code> object may be obtained from
    JNDI instead (using <code class="literal">&lt;jee:jndi-lookup&gt;</code>). The
    Spring-based message listeners can then interact with the server-hosted
    <code class="interfacename">ResourceAdapter</code>, also using the server's
    built-in <code class="interfacename">WorkManager</code>.</p><p>Please consult the JavaDoc for
    <code class="classname">JmsMessageEndpointManager</code>,
    <code class="classname">JmsActivationSpecConfig</code>, and
    <code class="classname">ResourceAdapterFactoryBean</code> for more details.</p><p>Spring also provides a generic JCA message endpoint manager which is
    not tied to JMS:
    <code class="classname">org.springframework.jca.endpoint.GenericMessageEndpointManager</code>.
    This component allows for using any message listener type (e.g. a CCI
    MessageListener) and any provider-specific ActivationSpec object. Check
    out your JCA provider's documentation to find out about the actual
    capabilities of your connector, and consult
    <code class="classname">GenericMessageEndpointManager</code>'s JavaDoc for the
    Spring-specific configuration details.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.gif"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>JCA-based message endpoint management is very analogous to EJB 2.1
      Message-Driven Beans; it uses the same underlying resource provider
      contract. Like with EJB 2.1 MDBs, any message listener interface
      supported by your JCA provider can be used in the Spring context as
      well. Spring nevertheless provides explicit 'convenience' support for
      JMS, simply because JMS is the most common endpoint API used with the
      JCA endpoint management contract.</p></td></tr></table></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="jms-namespace"></a>22.6&nbsp;JMS Namespace Support</h2></div></div></div><p>Spring 2.5 introduces an XML namespace for simplifying JMS
    configuration. To use the JMS namespace elements you will need to
    reference the JMS schema:</p><pre class="programlisting">&lt;<span class="hl-tag">?xml version="1.0" encoding="UTF-8"?</span>&gt;
&lt;<span class="hl-tag">beans</span> <span class="hl-attribute">xmlns</span>=<span class="hl-value">"http://www.springframework.org/schema/beans"</span>
       <span class="hl-attribute">xmlns:xsi</span>=<span class="hl-value">"http://www.w3.org/2001/XMLSchema-instance"</span>
       <span class="hl-attribute">xmlns:jms</span>=<span class="hl-value">"http://www.springframework.org/schema/jms"</span>
       <span class="hl-attribute">xsi:schemaLocation</span>=<span class="hl-value">"
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd"</span>&gt;

&lt;<span class="hl-comment">!-- &lt;bean/&gt; definitions here --</span>&gt;

&lt;<span class="hl-tag">/beans</span>&gt;</pre><p>The namespace consists of two top-level elements:
    <code class="literal">&lt;listener-container/&gt;</code> and
    <code class="literal">&lt;jca-listener-container/&gt;</code> both of which may
    contain one or more <code class="literal">&lt;listener/&gt;</code> child elements.
    Here is an example of a basic configuration for two listeners.</p><pre class="programlisting">&lt;<span class="hl-tag">jms:listener-container</span>&gt;

    &lt;<span class="hl-tag">jms:listener</span> <span class="hl-attribute">destination</span>=<span class="hl-value">"queue.orders"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"orderService"</span> <span class="hl-attribute">method</span>=<span class="hl-value">"placeOrder"</span>/&gt;

    &lt;<span class="hl-tag">jms:listener</span> <span class="hl-attribute">destination</span>=<span class="hl-value">"queue.confirmations"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"confirmationLogger"</span> <span class="hl-attribute">method</span>=<span class="hl-value">"log"</span>/&gt;

&lt;<span class="hl-tag">/jms:listener-container</span>&gt;</pre><p>The example above is equivalent to creating two distinct listener
    container bean definitions and two distinct
    <code class="classname">MessageListenerAdapter</code> bean definitions as
    demonstrated in <a class="xref" href="jms.html#jms-receiving-async-message-listener-adapter" title="22.4.4&nbsp;The MessageListenerAdapter">Section&nbsp;22.4.4, &#8220;The MessageListenerAdapter&#8221;</a>.
    In addition to the attributes shown above, the <code class="literal">listener</code> element
    may contain several optional ones. The following table describes all available
    attributes:</p><div class="table"><a name="jms-namespace-listener-tbl"></a><p class="title"><b>Table&nbsp;22.1.&nbsp;Attributes of the JMS <code class="literal">&lt;listener&gt;</code>
      element</b></p><div class="table-contents"><table summary="Attributes of the JMS <listener&gt;&#xA;      element" style="border-collapse: collapse;border-top: 1.0pt solid ; border-bottom: 1.0pt solid ; border-left: 1.0pt solid ; border-right: 1.0pt solid ; "><colgroup><col><col></colgroup><thead><tr><th style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">Attribute</th><th style="border-bottom: 1.0pt solid ; ">Description</th></tr></thead><tbody><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">id</td><td style="border-bottom: 1.0pt solid ; "><p>A bean name for the hosting listener container. If
            not specified, a bean name will be automatically
            generated.</p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">destination <span class="bold"><strong>(required)</strong></span></td><td style="border-bottom: 1.0pt solid ; "><p>The destination name for this listener, resolved
            through the <code class="interfacename">DestinationResolver</code>
            strategy.</p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">ref <span class="bold"><strong>(required)</strong></span></td><td style="border-bottom: 1.0pt solid ; "><p>The bean name of the handler object.</p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">method</td><td style="border-bottom: 1.0pt solid ; "><p>The name of the handler method to invoke. If the
            <code class="literal">ref</code> points to a
            <code class="interfacename">MessageListener</code> or Spring
            <code class="interfacename">SessionAwareMessageListener</code>, this
            attribute may be omitted.</p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">response-destination</td><td style="border-bottom: 1.0pt solid ; "><p>The name of the default response destination to send
            response messages to. This will be applied in case of a request
            message that does not carry a "JMSReplyTo" field. The type of this
            destination will be determined by the listener-container's
            "destination-type" attribute. Note: This only applies to a
            listener method with a return value, for which each result object
            will be converted into a response message.</p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">subscription</td><td style="border-bottom: 1.0pt solid ; "><p>The name of the durable subscription, if
            any.</p></td></tr><tr><td style="border-right: 1.0pt solid ; ">selector</td><td style=""><p>An optional message selector for this
            listener.</p></td></tr></tbody></table></div></div><br class="table-break"><p>The <code class="literal">&lt;listener-container/&gt;</code> element also
    accepts several optional attributes. This allows for customization of the
    various strategies (for example, <span class="property">taskExecutor</span> and
    <span class="property">destinationResolver</span>) as well as basic JMS settings
    and resource references. Using these attributes, it is possible to define
    highly-customized listener containers while still benefiting from the
    convenience of the namespace.</p><pre class="programlisting">&lt;<span class="hl-tag">jms:listener-container</span> <span class="hl-attribute">connection-factory</span>=<span class="hl-value">"myConnectionFactory"</span>
                        <span class="hl-attribute">task-executor</span>=<span class="hl-value">"myTaskExecutor"</span>
                        <span class="hl-attribute">destination-resolver</span>=<span class="hl-value">"myDestinationResolver"</span>
                        <span class="hl-attribute">transaction-manager</span>=<span class="hl-value">"myTransactionManager"</span>
                        <span class="hl-attribute">concurrency</span>=<span class="hl-value">"10"</span>&gt;

    &lt;<span class="hl-tag">jms:listener</span> <span class="hl-attribute">destination</span>=<span class="hl-value">"queue.orders"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"orderService"</span> <span class="hl-attribute">method</span>=<span class="hl-value">"placeOrder"</span>/&gt;

    &lt;<span class="hl-tag">jms:listener</span> <span class="hl-attribute">destination</span>=<span class="hl-value">"queue.confirmations"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"confirmationLogger"</span> <span class="hl-attribute">method</span>=<span class="hl-value">"log"</span>/&gt;

&lt;<span class="hl-tag">/jms:listener-container</span>&gt;</pre><p>The following table describes all available attributes. Consult the
    class-level Javadoc of the
    <code class="classname">AbstractMessageListenerContainer</code> and its concrete
    subclasses for more details on the individual properties. The Javadoc also
    provides a discussion of transaction choices and message redelivery
    scenarios.</p><div class="table"><a name="jms-namespace-listener-container-tbl"></a><p class="title"><b>Table&nbsp;22.2.&nbsp;Attributes of the JMS
      <code class="literal">&lt;listener-container&gt;</code> element</b></p><div class="table-contents"><table summary="Attributes of the JMS&#xA;      <listener-container&gt; element" style="border-collapse: collapse;border-top: 1.0pt solid ; border-bottom: 1.0pt solid ; border-left: 1.0pt solid ; border-right: 1.0pt solid ; "><colgroup><col><col></colgroup><thead><tr><th style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">Attribute</th><th style="border-bottom: 1.0pt solid ; ">Description</th></tr></thead><tbody><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">container-type</td><td style="border-bottom: 1.0pt solid ; "><p>The type of this listener container. Available
            options are: <code class="literal">default</code>,
            <code class="literal">simple</code>, <code class="literal">default102</code>, or
            <code class="literal">simple102</code> (the default value is
            <code class="literal">'default'</code>).</p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">connection-factory</td><td style="border-bottom: 1.0pt solid ; "><p>A reference to the JMS
            <code class="interfacename">ConnectionFactory</code> bean (the default
            bean name is
            <code class="literal">'connectionFactory'</code>).</p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">task-executor</td><td style="border-bottom: 1.0pt solid ; "><p>A reference to the Spring
            <code class="interfacename">TaskExecutor</code> for the JMS listener
            invokers.</p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">destination-resolver</td><td style="border-bottom: 1.0pt solid ; "><p>A reference to the
            <code class="interfacename">DestinationResolver</code> strategy for
            resolving JMS
            <code class="interfacename">Destinations</code>.</p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">message-converter</td><td style="border-bottom: 1.0pt solid ; "><p>A reference to the
            <code class="interfacename">MessageConverter</code> strategy for
            converting JMS Messages to listener method arguments. Default is a
            <code class="classname">SimpleMessageConverter</code>.</p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">destination-type</td><td style="border-bottom: 1.0pt solid ; "><p>The JMS destination type for this listener:
            <code class="literal">queue</code>, <code class="literal">topic</code> or
            <code class="literal">durableTopic</code>. The default is
            <code class="literal">queue</code>.</p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">client-id</td><td style="border-bottom: 1.0pt solid ; "><p>The JMS client id for this listener container. Needs
            to be specified when using durable subscriptions.</p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">cache</td><td style="border-bottom: 1.0pt solid ; "><p>The cache level for JMS resources:
            <code class="literal">none</code>, <code class="literal">connection</code>,
            <code class="literal">session</code>, <code class="literal">consumer</code> or
            <code class="literal">auto</code>. By default (<code class="literal">auto</code>), the
            cache level will effectively be "consumer", unless an external
            transaction manager has been specified - in which case the
            effective default will be <code class="literal">none</code> (assuming
            Java EE-style transaction management where the given
            ConnectionFactory is an XA-aware pool).</p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">acknowledge</td><td style="border-bottom: 1.0pt solid ; "><p>The native JMS acknowledge mode:
            <code class="literal">auto</code>, <code class="literal">client</code>,
            <code class="literal">dups-ok</code> or <code class="literal">transacted</code>. A
            value of <code class="literal">transacted</code> activates a locally
            transacted <code class="interfacename">Session</code>. As an
            alternative, specify the <code class="literal">transaction-manager</code>
            attribute described below. Default is
            <code class="literal">auto</code>.</p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">transaction-manager</td><td style="border-bottom: 1.0pt solid ; "><p>A reference to an external
            <code class="interfacename">PlatformTransactionManager</code>
            (typically an XA-based transaction coordinator, e.g. Spring's
            <code class="classname">JtaTransactionManager</code>). If not specified,
            native acknowledging will be used (see "acknowledge"
            attribute).</p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">concurrency</td><td style="border-bottom: 1.0pt solid ; "><p>The number of concurrent sessions/consumers to start
            for each listener. Can either be a simple number indicating the
            maximum number (e.g. "5") or a range indicating the lower as well
            as the upper limit (e.g. "3-5"). Note that a specified minimum is
            just a hint and might be ignored at runtime. Default is 1; keep
            concurrency limited to 1 in case of a topic listener or if queue
            ordering is important; consider raising it for general
            queues.</p></td></tr><tr><td style="border-right: 1.0pt solid ; ">prefetch</td><td style=""><p>The maximum number of messages to load into a single
            session. Note that raising this number might lead to starvation of
            concurrent consumers!</p></td></tr></tbody></table></div></div><br class="table-break"><p>Configuring a JCA-based listener container with the "jms" schema
    support is very similar.</p><pre class="programlisting">&lt;<span class="hl-tag">jms:jca-listener-container</span> <span class="hl-attribute">resource-adapter</span>=<span class="hl-value">"myResourceAdapter"</span>
                            <span class="hl-attribute">destination-resolver</span>=<span class="hl-value">"myDestinationResolver"</span>
                            <span class="hl-attribute">transaction-manager</span>=<span class="hl-value">"myTransactionManager"</span>
                            <span class="hl-attribute">concurrency</span>=<span class="hl-value">"10"</span>&gt;

    &lt;<span class="hl-tag">jms:listener</span> <span class="hl-attribute">destination</span>=<span class="hl-value">"queue.orders"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"myMessageListener"</span>/&gt;

&lt;<span class="hl-tag">/jms:jca-listener-container</span>&gt;</pre><p>The available configuration options for the JCA variant are
    described in the following table:</p><div class="table"><a name="jms-namespace-jca-listener-container-tbl"></a><p class="title"><b>Table&nbsp;22.3.&nbsp;Attributes of the JMS
      <code class="literal">&lt;jca-listener-container/&gt;</code> element</b></p><div class="table-contents"><table summary="Attributes of the JMS&#xA;      <jca-listener-container/&gt; element" style="border-collapse: collapse;border-top: 1.0pt solid ; border-bottom: 1.0pt solid ; border-left: 1.0pt solid ; border-right: 1.0pt solid ; "><colgroup><col><col></colgroup><thead><tr><th style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">Attribute</th><th style="border-bottom: 1.0pt solid ; ">Description</th></tr></thead><tbody><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">resource-adapter</td><td style="border-bottom: 1.0pt solid ; "><p>A reference to the JCA
            <code class="interfacename">ResourceAdapter</code> bean (the default
            bean name is <code class="literal">'resourceAdapter'</code>).</p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">activation-spec-factory</td><td style="border-bottom: 1.0pt solid ; "><p>A reference to the
            <code class="interfacename">JmsActivationSpecFactory</code>. The
            default is to autodetect the JMS provider and its
            <code class="interfacename">ActivationSpec</code> class (see
            <code class="classname">DefaultJmsActivationSpecFactory</code>)</p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">destination-resolver</td><td style="border-bottom: 1.0pt solid ; "><p>A reference to the
            <code class="interfacename">DestinationResolver</code> strategy for
            resolving JMS <code class="interfacename">Destinations</code>.
            </p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">message-converter</td><td style="border-bottom: 1.0pt solid ; "><p>A reference to the
            <code class="interfacename">MessageConverter</code> strategy for
            converting JMS Messages to listener method arguments. Default is a
            <code class="classname">SimpleMessageConverter</code>.</p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">destination-type</td><td style="border-bottom: 1.0pt solid ; "><p>The JMS destination type for this listener:
            <code class="literal">queue</code>, <code class="literal">topic</code> or
            <code class="literal">durableTopic</code>. The default is
            <code class="literal">queue</code>.</p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">client-id</td><td style="border-bottom: 1.0pt solid ; "><p>The JMS client id for this listener container. Needs
            to be specified when using durable subscriptions.</p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">acknowledge</td><td style="border-bottom: 1.0pt solid ; "><p>The native JMS acknowledge mode:
            <code class="literal">auto</code>, <code class="literal">client</code>,
            <code class="literal">dups-ok</code> or <code class="literal">transacted</code>. A
            value of <code class="literal">transacted</code> activates a locally
            transacted <code class="interfacename">Session</code>. As an
            alternative, specify the <code class="literal">transaction-manager</code>
            attribute described below. Default is
            <code class="literal">auto</code>.</p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">transaction-manager</td><td style="border-bottom: 1.0pt solid ; "><p>A reference to a Spring
            <code class="classname">JtaTransactionManager</code> or a
            <code class="interfacename">javax.transaction.TransactionManager</code>
            for kicking off an XA transaction for each incoming message. If
            not specified, native acknowledging will be used (see the
            "acknowledge" attribute).</p></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">concurrency</td><td style="border-bottom: 1.0pt solid ; "><p>The number of concurrent sessions/consumers to start
            for each listener. Can either be a simple number indicating the
            maximum number (e.g. "5") or a range indicating the lower as well
            as the upper limit (e.g. "3-5"). Note that a specified minimum is
            just a hint and will typically be ignored at runtime when using a
            JCA listener container. Default is 1.</p></td></tr><tr><td style="border-right: 1.0pt solid ; ">prefetch</td><td style=""><p>The maximum number of messages to load into a single
            session. Note that raising this number might lead to starvation of
            concurrent consumers!</p></td></tr></tbody></table></div></div><br class="table-break"></div></div><!--Begin LoopFuse code--><script src="http://loopfuse.net/webrecorder/js/listen.js" type="text/javascript"></script><script type="text/javascript">
			_lf_cid = "LF_48be82fa";
			_lf_remora();
		</script><!--End LoopFuse code--><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ejb.html">Prev</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="spring-integration.html">Up</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="jmx.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">21.&nbsp;Enterprise JavaBeans (EJB) integration&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;23.&nbsp;JMX</td></tr></table></div></body></html>